import { FC, useEffect, useState, Fragment, useRef } from 'react'
import { fetchShoplist, set_three_arr } from './classifySlice'
import { useAppDispatch, useAppSelector } from 'store/hooks'
import './classify.scss'
import { useNavigate } from 'react-router-dom'
import { ImageView } from 'components'
// classify
const Classify: FC = () => {
  const [leftArr, setLeftArr] = useState<string[]>([])
  const [offsetTopArr, setOffsetTopArr] = useState<number[]>([])
  const [tabIndex, setTabIndex] = useState<number>(0)
  // 设置一个开关，控制tab和scroll互相不影响
  const [isScroll, setIsScroll] = useState<boolean>(false)
  const contentWrapper = useRef<HTMLDivElement | null>(null)
  const store = useAppSelector((s) => s.classify)
  // dispatch
  const dispatch = useAppDispatch()
  // router
  const navigate = useNavigate()

  useEffect(() => {
    // 数据请求
    dispatch(fetchShoplist())
  }, [])

  /**
   * @name 两个异步与楼层滚动效果的关系
   * 1. 数据异步
   * 2. 图片异步（没有解决导致获取的offsetTop不对，改变的策略就是给图片设置固定的宽高）
   */

  useEffect(() => {
    // offsetTop是距离有定位父元素的的距离，如果父亲元素都没有定位，那最终就会找到body
    // 获取每一个right-item-box的offsetTop值 [0]
    // 上一个元素的offsetHeight 元素本身的高度
    const target: NodeListOf<HTMLDivElement> = document.querySelectorAll('.right-item-box')
    let arr: number[] = []
    target.forEach((item) => {
      arr.push(item.offsetTop)
    })
    setOffsetTopArr(arr)
    // 等store内部请求完毕数据之后，再提交默认第一个tab按钮的类型下的所有的数据
    dispatch(set_three_arr(0))
  }, [store.list])

  useEffect(() => {
    console.log('offsetTopArr:', offsetTopArr)
  }, [offsetTopArr])

  useEffect(() => {
    // classifyType
    const myList = [...store.list]
    const arr: string[] = []
    myList.forEach((item) => {
      arr.push(item.classifyType)
    })
    setLeftArr(() => arr)
  }, [store.list])

  /**
   * 问题：
   * 1. 当用户点击左侧tab按钮的时候，触发了右侧的滚动事件
   * 2. 滚动事件在设置下标的时候，是基于滚动条滚动的时候设置的，
   * 3. 可能会导致下标设置不准确
   * 解决方案：
   * 1. 互相影响（不让他互相影响）开 关
   *
   */

  // 左侧的点击按钮
  const handleTabClick = (index: number) => {
    // 关闭滚动监听
    setIsScroll(false)
    // tab切换高亮；
    setTabIndex(index)
    if (contentWrapper.current) {
      contentWrapper.current.scrollTop = (
        document.querySelectorAll('.right-item-box')[index] as HTMLDivElement
      ).offsetTop
    }
    dispatch(set_three_arr(index))
  }
  // 右侧的滚动事件
  const handleScroll = () => {
    // 开通滚动监听
    setIsScroll(true)
    // item: 监听到的元素
    offsetTopArr.forEach((v, i) => {
      if (contentWrapper.current) {
        if (contentWrapper.current.scrollTop >= v) {
          if (isScroll) {
            setTabIndex(i)
          }
        }
      }
    })
  }

  // 剩下的逻辑都在组件内部写

  return (
    <div className={'container'}>
      <ul className={'left'}>
        {leftArr.length ? (
          <>
            {leftArr.length &&
              leftArr.map((item, index) => {
                return (
                  <li
                    className={tabIndex === index ? `active-li` : ''}
                    onClick={() => handleTabClick(index)}
                    key={item}
                  >
                    {item}
                  </li>
                )
              })}
          </>
        ) : null}
      </ul>
      <div className={'right'} onScroll={handleScroll} ref={contentWrapper}>
        <div className="right-content">
          {store.list.length &&
            store.list.map((item) => {
              return (
                <div className="right-item-box" key={item.id}>
                  <h1 className="title-type">{item.classifyType}</h1>
                  <ul className={'right-list-wrapper'}>
                    {item.children &&
                      item.children.map((v, i) => {
                        return (
                          <ol
                            onClick={() => {
                              // 每次点击一个item数据。就将这个数据的children提交给redux,
                              // 让tab页面，通过redux拿取数据
                              navigate(`/tab?tab=${tabIndex}`)
                            }}
                            className="right-list-item"
                            key={i}
                          >
                            {/* 通过给图片懒加载效果的占位图设置固定的宽高，让图片在没有加载出来之前也有宽高，这样子
                            就能保证获取到的元素的offsetTop值不会有错误，才能跟滚动条的scrollTop做对比
                            */}
                            <li style={{ width: 70, height: 70 }}>
                              <ImageView src={v.img}></ImageView>
                            </li>
                            <li className={'font-msg'}>
                              <span style={{ color: 'red' }}>{item.classifyType}</span>:{v.title}
                            </li>
                          </ol>
                        )
                      })}
                  </ul>
                </div>
              )
            })}
        </div>
      </div>
    </div>
  )
}

export default Classify
